﻿using BCCommon;
using BCCommon.Enums;
using BCCommon.PaymentEnums;
using BCData.Common.Payment.Payment;
using BCDto.Common.Payment.Payment;
using BCDto.Common.Payment.PaymentRecord;
using BCDto.Common.Wallet;
using BCDto.Sim.Admin.Admin;
using BCDto.Website.User;
using BCEntity.Common.Payment.Payment;
using BCService.Common.Wallet;
using System;
using System.Collections.Generic;

namespace BCService.Common.Payment.Payment
{
    public class CashPayService : ICashPayService
    {
        private readonly IPaymentRecordData paymentRecordData;
        private readonly IWalletService walletService;

        public SourceAppType AppType { get; set; }
        public SourceOSType OSType { get; set; }
        public PaymentChannelType ChannelType { get; set; }

        public CashPayService( IPaymentRecordData paymentRecordData, IWalletService walletService)
        {
            this.paymentRecordData = paymentRecordData;
            this.walletService = walletService;
        }

        public decimal? GetBalance(UserDto userDto)
        {
            return null;
        }

        public decimal? GetLimit(UserDto userDto)
        {
            return null;
        }

        public decimal? GetAgentBalance(long agentRecordId)
        {
            return null;
        }

        public decimal? GetAgentLimit(long agentRecordId)
        {
            return null;
        }

        public IDictionary<string, object> AuthLoginInfo(string auth_code, SourceAppType appType, SourceOSType osType, UserDto userDto)
        {
            throw new ArgumentException("线下支付不支持登录授权");
        }

        public IDictionary<string, string> CreateAppAuthLogin(SourceAppType appType, SourceOSType osType, UserDto userDto)
        {
            throw new NotImplementedException();
        }

        public PaymentQRCodeDto GenerateQRCode(SourceAppType appType, FlowType orderType, string subject, string referenceNumber, SourceOSType osType, SourceDeviceType deviceType, string deviceId, IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer, UserDto userDto)
        {
            throw new NotImplementedException();
        }
        public PaymentQRCodeDto AgentGenerateQRCode(SourceAppType appType, FlowType orderType, string subject,
string referenceNumber, SourceOSType osType, SourceDeviceType deviceType, string deviceId,
IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer, AdminDto admin)
        {
            throw new NotImplementedException();
        }
        public ReceiveNotificationDto ReceiveNotification(IDictionary<string, string> parameters, out PaymentDto paymentDto)
        {
            throw new NotImplementedException();
        }

        public decimal Refund(long adminId, string adminFullName, long recordId, decimal refundAmount)
        {
            throw new NotImplementedException();
        }

        public decimal Transfer(SourceAppType appType, SourceOSType osType, long recordId, decimal transferAmount, long userId, string open_userid, UserDto userDto)
        {
            throw new NotImplementedException();
        }

        public PaymentDto TryPay(SourceAppType appType, FlowType orderType, string subject, string referenceNumber, SourceOSType osType, SourceDeviceType deviceType, string deviceId, IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer,UserDto userDto)
        {
            decimal newAmount = Math.Round(amount, 2);
            PaymentRecordEntity entity = this.paymentRecordData.Create(this.ChannelType, orderType.ToString(),subject, referenceNumber, newAmount, userDto.UserId, appType, osType, payer);
            entity = this.paymentRecordData.SetAsToBeConfirmed(entity.PaymentRecordId);
            return new PaymentDto
            {
                PaymentRecordId = entity.PaymentRecordId,
                OrderType = orderType,
                ReferenceNumber = referenceNumber,
                PayChannelType = this.ChannelType,
                OriginalAmount = newAmount,
                Discount = 0,
                PaidAmount = newAmount,
                Result = PaymentResultType.ToBeConfirmed,
                Parameters = new Dictionary<string, string>
                {
                    { "Cash", newAmount.ToString() }
                }
            };
        }

        public PaymentDto AgentTryPay(SourceAppType appType, FlowType orderType, string subject, string referenceNumber, SourceOSType osType, 
            SourceDeviceType deviceType, string deviceId, IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer,
            AdminDto admin)
        {
            decimal newAmount = Math.Round(amount, 2);
            PaymentRecordEntity entity = this.paymentRecordData.Create(this.ChannelType, orderType.ToString(), subject, referenceNumber,
                newAmount, null, appType, osType, payer);
            entity = this.paymentRecordData.SetAsToBeConfirmed(entity.PaymentRecordId);
            return new PaymentDto
            {
                PaymentRecordId = entity.PaymentRecordId,
                OrderType = orderType,
                ReferenceNumber = referenceNumber,
                PayChannelType = this.ChannelType,
                OriginalAmount = newAmount,
                Discount = 0,
                PaidAmount = newAmount,
                Result = PaymentResultType.ToBeConfirmed,
                Parameters = new Dictionary<string, string>
                {
                    { "Cash", newAmount.ToString() }
                }
            };
        }

        public bool ConfirmPayValidation(long paymentRecordId, string referenceNumber, string password,UserDto userDto)
        {
            PaymentRecordEntity paymentRecordEntity = this.paymentRecordData.GetPaymentRecordByPaymentRecordId(paymentRecordId);
            if (paymentRecordEntity.Status == PaymentResultType.Success.ToString())
            {
                throw new ArgumentException("此订单已支付完成，请勿重复支付");
            }
            if (paymentRecordEntity.UserId != userDto.UserId)
            {
                throw new ArgumentException("请勿支付不属于您的订单");
            }
            if (paymentRecordEntity.ReferenceNumber != referenceNumber)
            {
                throw new ArgumentException("订单编号错误，请确认支付订单编号");
            }
            WalletDto walletDto = this.walletService.GetWalletByUserId(userDto.UserId, true);
            if (!walletDto.HasPayPwd)
            {
                throw new ArgumentException("未设置支付密码，无法完成支付");
            }
            if (walletDto.PasswordErrorCount == 3)
            {
                throw new ArgumentException("输入密码错误次数太多，请稍后再试");
            }
            if (!password.SHA256(userDto.Phone).Equals(walletDto.PayPassword))
            {
                this.walletService.UpdatePasswordErrorCount(userDto.UserId, walletDto.PasswordErrorCount++);
                throw new ArgumentException("支付密码错误");
            }
            PaymentRecordEntity paymentRecordEntityResult = this.paymentRecordData.SetAsSuccess(paymentRecordId);
            return paymentRecordEntityResult.Status == PaymentResultType.Success.ToString();
        }

        public PaymentRecordDto SyncCheckSign(IDictionary<string, string> parameters)
        {
            throw new NotImplementedException();
        }

        public PaymentRecordDto Synchronize(long paymentRecordId, PaymentSynchronizeRequestDto requestDto)
        {
            throw new NotImplementedException();
        }
    }
}
